/**************************************************************************************
 * @file      :lcd.c
 * @author    :WQY (18911638385@163.com)
 * @brief     :LCD实现
 * @version   :0.1
 * @date      :2019-12-06
 * 
 * @copyright : Copyright (c) 2019
 * 
 ***************************************************************************************/

#include "lcd.h"
 
int color_array[7] = {RED,ORANGE,YEA,GREEN,BLUE,DIAN,PERPO};

/**************************************************************************************
 * @brief 打开LCD进行，内存映射
 * 
 * @param lcd_p  
 * @return int 
 ***************************************************************************************/
int lcd_open(int **lcd_p)
{
	int lcd_fd = open("/dev/fb0",O_RDWR); 
	if(-1 == lcd_fd){
		perror("open src file");	
	}
    *lcd_p = mmap(NULL, WIDTH*HIGHT*4, PROT_WRITE|PROT_READ, MAP_SHARED, lcd_fd, 0);
     if((void *)-1 == lcd_p){
        perror("mmap");
        return -1;
     }     
    return lcd_fd;
}


/************************************************************************
 * @brief     :Set the piex color object
 * @param     :addr 
 * @param     :x 
 * @param     :y 
 * @param     :color 
 ************************************************************************/
void set_piex_color(int *addr,int x,int y,int color)
{
    *(addr + x*WIDTH+y) = color;
}


/************************************************************************
 * @brief     :画矩形
 * @param     :addr 内存映射的地址
 * @param     :s_x  x方向起始位置
 * @param     :s_y  y方向起始位置
 * @param     :w   矩形宽度
 * @param     :h   矩形宽度
 * @param     :color 矩形颜色
 ************************************************************************/
void draw_rectangle(int *addr, int s_x, int s_y, int w, int h,int color)
{
    int i,j;
    for(i = s_x; i < h+s_x; i++){
        for(j = s_y; j < w+s_y; j++){
            set_piex_color(addr, i, j, color);
         }
    }
}

/************************************************************************
 * @brief     :画直线
 * @param     :addr 内存映射的地址
 * @param     :s_x  x方向起始位置
 * @param     :s_y  y方向起始位置
 * @param     :w   直线宽度
 * @param     :l   直线长度
 * @param     :color 矩形颜色
 * @param     :mod 直线方向
 ************************************************************************/
void draw_line(int *addr, int s_x, int s_y, int w, int l,int color,int mod)
{
    int i,j;
    if(2 == mod){                               /*垂直直线*/
        for(i = s_x; i < l+s_x; i++){
            for(j = s_y; j < w+s_y; j++){
                set_piex_color(addr, i, j, color);
            }
        }
    }else{                                     /*水平直线*/             
         for(i = s_y; i < l+s_y; i++){
            for(j = s_x; j < w+s_x; j++){
                set_piex_color(addr, j, i, color);
            }
        }       
    }
}


/************************************************************************
 * @brief     :画矩形框
 * @param     :addr 内存映射的地址
 * @param     :s_x  x方向起始位置
 * @param     :s_y  y方向起始位置
 * @param     :w   矩形宽度
 * @param     :l   直线长度
 * @param     :color 矩形颜色
 * @param     :wl 矩形线宽
 ************************************************************************/
void draw_rectangle_box(int *addr, int s_x, int s_y, int w, int h,int wl ,int color)
{
    draw_line(addr, s_x, s_y, wl, w,color,1);   /*上水平*/
    draw_line(addr, s_x, s_y, wl, h,color,2);   /*左垂直*/
    draw_line(addr, s_x, s_y+w, wl, h,color,2);   /*右垂直*/
    draw_line(addr, s_x+h, s_y, wl, w,color,1);   /*下水平*/      
}

/************************************************************************
 * @brief     :
 * @param     :addr 
 * @param     :c_x 
 * @param     :c_y 
 * @param     :r 
 * @param     :color 
 * @param     :mod 
 ************************************************************************/
void draw_circle(int *addr, int c_x, int c_y, float r,int color,int mod)
{
    int i,j;
   
      for(i = c_x - r; i <c_x+r; i++)        //x
        for(j = c_y - r; j <c_y+r; j++){
                if(r*r >= (i-c_x)*(i-c_x)+(j-c_y)*(j-c_y))
                    set_piex_color(addr, i, j, color); 
        }
      if(1 == mod)
        return ;
       r -= 5;
       for(i = c_x - r; i <c_x+r; i++)        //x
        for(j = c_y - r; j <c_y+r; j++){
                if(r*r >= (i-c_x)*(i-c_x)+(j-c_y)*(j-c_y))
                    set_piex_color(addr, i, j, WHITE); 
        }           
        
}

/************************************************************************
 * @brief     :清除屏幕
 * @param     :addr 内存映射的地址
 * @param     :color 颜色
 ************************************************************************/
void lcd_clear(int *addr,int color)
{
    int j,i;
    for(i= 0; i < HIGHT; i++)
        for(j = 0; j < WIDTH; j++)
            set_piex_color(addr, i, j, color);       
}



/**************************************************************************************
 * @brief 在指定位置显示一张指定大小的图片
 * 
 * @param addr 
 * @param bmp_file 
 * @param x 
 * @param y 
 * @param w 
 * @param h 
 * @return int 
 ***************************************************************************************/
int show_bmp( int *addr,const char *bmp_file,int x,int y,int w, int h)
{
    int i,j,k = 0;
    FILE *pic_fd = NULL;

    while(3 * w % 4 != 0){                /*行数据4字节对齐*/
        w++;
    }
    //printf("w :%d\n",w); 

    union COLOR
    {
        int color;
        char buf[4];
    }lcd_dis;

    if(w > WIDTH)w = WIDTH;
    if(h > HIGHT)h = HIGHT;

    char *bmp_buf =  calloc(sizeof(char),w*h*3) ; 
    if(NULL == bmp_buf){
        printf("bmp_buf error !\n");
        return -1;
    }else{
        //printf("bmp_buf: %p\n",bmp_buf);
    }

    int *lcd_buf = calloc(sizeof(int),w*h) ; 
    if(NULL == lcd_buf){
        printf("lcd_buf error !\n");
        return -1;
    }else{
       // printf("lcd_buf: %p\n",lcd_buf);
    }

    int *show_buf =  calloc(sizeof(int),w*h) ;  
    if(NULL == show_buf){
        printf("show_buf error !\n");
        return -1;
    }else{
        //printf("show_buf:%p\n",show_buf);
    }
    /*打开文件,可读可写*/
    pic_fd = fopen(bmp_file, "r+");
    if(NULL == pic_fd){
        printf("fopen error!\n");
        return -1;
    }

    fseek(pic_fd,54,SEEK_SET);    /*偏移54个字节*/

    int ret = fread(bmp_buf, h*w*3, 1, pic_fd);
    if(ret != 1){
        printf("read error!\n");
        return -1;
    }
    
	for(i=0,j=0; j<w*h*3; i++,j+=3)
	{
		lcd_dis.buf[0] = bmp_buf[j];
		lcd_dis.buf[1] = bmp_buf[j+1];
		lcd_dis.buf[2] = bmp_buf[j+2];
		lcd_dis.buf[3] = 0;
        lcd_buf[i] = lcd_dis.color;       
	}
     /*位置调换*/     
    for(i = 0,j = h-1; i < h; i++,j--){
        memcpy(show_buf+w*i,lcd_buf+j*w,w*4);
    }

    y = (WIDTH-w)/2;                                    /*居中显示*/
    x = (HIGHT-h)/2; 
 
    /*显示图片*/
    for(i = x,k = 0; i < h+x; i++){
        for(j = y; j < w+y; j++){
             set_piex_color(addr, i, j, show_buf[k++]); 
        }
    }
      
    free(bmp_buf);
    free(show_buf);
    free(lcd_buf);

    fclose(pic_fd);  
}


